package me.sdevil507.biz.screen.service.impl;

import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.SubQueryExpression;
import com.querydsl.core.types.dsl.*;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import me.sdevil507.biz.common.sysdict.po.QSysDict;
import me.sdevil507.biz.common.sysdict.service.SysdictService;
import me.sdevil507.biz.fruit.po.*;
import me.sdevil507.biz.fruit.service.FruitService;
import me.sdevil507.biz.screen.dto.ScreenActiveResultDTO;
import me.sdevil507.biz.screen.dto.ScreenSearchConditionDTO;
import me.sdevil507.biz.screen.dto.ScreenYearResultDTO;
import me.sdevil507.biz.screen.service.ScreenService;
import me.sdevil507.org.po.QOrgPo;
import me.sdevil507.org.repository.OrgRepository;
import me.sdevil507.org.service.OrgRoleService;
import me.sdevil507.services.dto.FruitInfoResultDTO;
import me.sdevil507.services.dto.ResultDTO;
import me.sdevil507.supports.shiro.helper.OrgAccountHelper;
import me.sdevil507.supports.shiro.helper.ServiceAccountHelper;
import me.sdevil507.supports.status.ComConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author hp
 * @Date 2021/2/24 17:02
 * @Description ServicesKeyWordServiceImpl
 * @Version 1.0
 */
@Service
public class ScreenServiceImpl implements ScreenService {

    @Autowired
    JPAQueryFactory jpaQueryFactory;
    @Autowired
    private SysdictService sysdictService;
    @Autowired
    private FruitService fruitService;
    @Autowired
    private OrgRoleService orgRoleService;
    @Autowired
    OrgRepository orgRepository;

    private  Predicate getFruitAndOrgRelPredicate(QFruitPO qFruitPO, QFruitOrgRelPo qFruitOrgRelPo, ScreenSearchConditionDTO dto){
        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()).and(qFruitPO.isPublic.eq("0")
                .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitPO.pubTime);

        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.loe(sdf.format(pubEndTime)));
        }

        List<String> fruitTypeList = dto.getFruitTypeList();
        if(!CollectionUtils.isEmpty(fruitTypeList)){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.in(fruitTypeList));
        }

        if(dto.getCnOrPs() == null){
            if (dto.getYearNumberList() != null && dto.getYearNumberList().length > 0) {
                predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.year().in(dto.getYearNumberList()));
            }
            if (dto.getYearNumber() != null) {
                predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.year().eq(dto.getYearNumber()));
            }
        }

        long orgId = dto.getOrgId();
        if (orgId > 0) {
            predicate = ExpressionUtils.and(predicate, qFruitOrgRelPo.orgId.eq(orgId));
        }

        Set<Long> orgIdList = dto.getOrgIdList();
        if(!CollectionUtils.isEmpty(orgIdList)){
            predicate = ExpressionUtils.and(predicate, qFruitOrgRelPo.orgId.in(orgIdList));
        }


        return predicate;
    }


    /**
     * -----------------------获取所有智库最新5条批示-----------------------
     *
     */
    @Override
    public List<ScreenActiveResultDTO> getOrgAllPsInfo(ScreenSearchConditionDTO dto) {
        JPAQuery<ScreenActiveResultDTO> psQuery = this.getPsActiveResult(dto);
        return psQuery.offset(5).limit(5).fetch();
    }

    public JPAQuery<ScreenActiveResultDTO> getPsActiveResult(ScreenSearchConditionDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QOrgPo qOrgPo = QOrgPo.orgPo;
        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));

        // 开启谓语查询条件
        Predicate predicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //查询批示动态
        JPAQuery<ScreenActiveResultDTO> queryPsResults = jpaQueryFactory.select(
                Projections.constructor(ScreenActiveResultDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qOrgPo.nameZh,
                        qFruitLeaderPO.inclinationLevelName,
                        qFruitLeaderPO.inclinationTime.as("fruitTime"),
                        queryAuthor
                )
        )
                .from(qFruitLeaderPO)
                .leftJoin(qFruitOrgRelPo).on(qFruitLeaderPO.fruitId.eq(qFruitOrgRelPo.fruitId))
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(predicate)
                .orderBy(
                        qFruitLeaderPO.inclinationTime.desc()
                );

        return queryPsResults;
    }


    /**
     * -----------------------获取所有智库成果、课题、咨政建言------------------------------------
     *
     * @return
     */
    @Override
    public Map getOrgProjectAndFruitInfo(ScreenSearchConditionDTO dto) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        Map map = new HashMap();

        // --------------------成果总数--------------------
        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //获取所有成果
        List<FruitInfoResultDTO> allFruitList = this.getAllFruit(qFruitPO, qFruitOrgRelPo, fruitPredicate);
//        map.put("allFruitNum", allFruitList.size());

        // --------------------咨政内参数xx篇（报送篇数、采纳篇数、批示篇数）--------------------
        map.put("allNcFruitNum",
                allFruitList.stream()
                        .filter(fruitInfoResultDTO ->
                                fruitInfoResultDTO.getType().equals(ComConstant.FruitType.InternalReferenceReport)
                        ).count());
        //报送篇数
//        long subFruitNum = fruitService.getFruitSubPiece("bs" , dto.getOrgIdList());
//        map.put("subFruitNum", subFruitNum);
        //采纳篇数
        long subCnFruitNum = fruitService.getFruitSubPiece("cn" ,dto);
        map.put("subCnFruitNum", subCnFruitNum);
        //批示篇数
        long psFruitNum = fruitService.getFruitPsPiece(dto);
        map.put("psFruitNum", psFruitNum);
        //批示篇数--正国级
        long psZgjFruitNum = fruitService.getFruitPsZgjPiece(dto);
        map.put("psZgjFruitNum", psZgjFruitNum);
        //批示篇数--副国级
        long psFgjFruitNum = fruitService.getFruitPsFgjPiece(dto);
        map.put("psFgjFruitNum", psFgjFruitNum);

        // --------------------理论成果统计  近一年--------------------
        //媒体 国家级以上
        map.put("mediaLevelNum", this.getFruitLevelAndDatePeriodCount(dto, "1", ComConstant.FruitType.NewspaperORNetwork, null));
        //采访 国际级以上
        map.put("interviewInternationalLevelNum", this.getFruitLevelAndDatePeriodCount(dto, "1", ComConstant.FruitType.NewspaperORNetwork, ComConstant.FruitType.MEDIA_INTERVIEW));
        //采访 国家级以上
        map.put("interviewCountryLevelNum", this.getFruitLevelAndDatePeriodCount(dto, "2", ComConstant.FruitType.NewspaperORNetwork, ComConstant.FruitType.MEDIA_INTERVIEW));
        //论文 统计所有
        map.put("lwAllNum", this.getFruitLevelAndDatePeriodCount(dto, "", ComConstant.FruitType.Paper, null));
        //图书 统计所有
        map.put("bookAllNum", this.getFruitLevelAndDatePeriodCount(dto, "", ComConstant.FruitType.BOOK, null));

        // --------------------智库活动统计  近一年--------------------
        map.put("activityAllNum", this.getFruitLevelAndDatePeriodCount(dto, "", ComConstant.FruitType.PolicyAdvice, null));

        // --------------------承担课题统计  近一年--------------------
        //承担课题 纵向 国家级以上
        map.put("projectLevelNum", this.getFruitLevelAndDatePeriodCount(dto, "1", ComConstant.FruitType.PROJECT, ComConstant.FruitType.VERTICAL));
        //承担课题 纵向 所有
        map.put("projectAllNum", this.getFruitLevelAndDatePeriodCount(dto, "", ComConstant.FruitType.PROJECT, ComConstant.FruitType.VERTICAL));

        return map;
    }

    private List<FruitInfoResultDTO> getAllFruit(QFruitPO qFruitPO, QFruitOrgRelPo qFruitOrgRelPo, Predicate predicate){
        return jpaQueryFactory.select(
                Projections.constructor(FruitInfoResultDTO.class,
                        qFruitPO.id,
                        qFruitPO.type
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO)
                .on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .where(predicate)
                .fetch();
    }

    @Override
    public Page<ScreenActiveResultDTO> getCnPsFruitOfPage(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getCnPsFruitData(dto);
        return new PageImpl<>((List<ScreenActiveResultDTO>)resultMap.get("resultList"), dto.getPageDto().getPageable(), Long.parseLong(resultMap.get("count")+""));
    }

    public Map<String, Object> getCnPsFruitData(ScreenSearchConditionDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;

        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //资政内参
        fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport));
        Integer cnOrPs = dto.getCnOrPs();
        if(cnOrPs != null){
            if(cnOrPs == 1){
                //包含采纳
                fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitSubPO.isAdopt.isTrue());
                if(dto.getYearNumber() != null){
                    fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitSubPO.adoptTime.year().eq(dto.getYearNumber()));
                }
                if(dto.getYearNumberList() != null && dto.getYearNumberList().length > 0){
                    fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitSubPO.adoptTime.year().in(dto.getYearNumberList()));
                }
                return this.getFruitInfo(dto, fruitPredicate, false, true,false);
            }else if(cnOrPs == 2){
                //包含批示
                fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitLeaderPO.inclinationLevel.in(dto.getNcPsTypeList()));
                if(dto.getYearNumber() != null){
                    fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitLeaderPO.inclinationTime.year().eq(dto.getYearNumber()));
                }
                if(dto.getYearNumberList() != null && dto.getYearNumberList().length > 0){
                    fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitLeaderPO.inclinationTime.year().in(dto.getYearNumberList()));
                }
                return this.getFruitInfo(dto, fruitPredicate, false, false,true);
            }
        }
        return null;
    }

    @Override
    public List<ScreenActiveResultDTO> getZzFruitInfo(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getZzFruitData(dto);

        return (List<ScreenActiveResultDTO>)resultMap.get("resultList");
    }

    @Override
    public Map<String, List<ScreenActiveResultDTO>>  getZzFruitForMaxLeader(ScreenSearchConditionDTO dto) {
        //有明确领导人或部门的省部级批示>普通省部级批示
        List<ScreenActiveResultDTO> queryFruitResultsOfNcPs = getZzFruitForMaxLeaderOfNcPs(dto);
        //国家级会议
        List<ScreenActiveResultDTO> queryFruitResultsOfMeeting = getZzFruitForMaxLeaderOfMeeting(dto);

        Map<String, List<ScreenActiveResultDTO>> map = new HashMap<>();
        map.put("maxLeaderPs", queryFruitResultsOfNcPs);
        map.put("maxLeaderMeeting", queryFruitResultsOfMeeting);

        return map;
    }

    private List<ScreenActiveResultDTO> getZzFruitForMaxLeaderOfNcPs(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QOrgPo qOrgPo = QOrgPo.orgPo;

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));

        Predicate leaderPsPredicate = qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport)
                .and(qFruitLeaderPO.inclinationLevel.loe("4"))
                .and(qFruitOrgRelPo.orgId.in(dto.getOrgIdList()));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitLeaderPO.inclinationTime);

        if (null != pubStartTime) {
            leaderPsPredicate = ExpressionUtils.and(leaderPsPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            leaderPsPredicate = ExpressionUtils.and(leaderPsPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }

        return this.getActivePsResults(leaderPsPredicate, qFruitPO, qFruitLeaderPO, qFruitOrgRelPo, qOrgPo, queryAuthor).limit(5).fetch();
    }

    private List<ScreenActiveResultDTO> getZzFruitForMaxLeaderOfMeeting(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QOrgPo qOrgPo = QOrgPo.orgPo;

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));

        //会议
        Predicate meetingPredicate = qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice)
                .and(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEETING).and(qFruitPO.awardsLevel.loe("2")))
                .and(qFruitOrgRelPo.orgId.in(dto.getOrgIdList()));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitPO.pubTime);

        if (null != pubStartTime) {
            meetingPredicate = ExpressionUtils.and(meetingPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            meetingPredicate = ExpressionUtils.and(meetingPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }

        return this.getActiveFruitResults(meetingPredicate, qFruitPO, qFruitLeaderPO, qFruitOrgRelPo, qOrgPo, queryAuthor).limit(5).fetch();
    }


    @Override
    public Page<ScreenActiveResultDTO> getZzFruitOfPage(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getZzFruitData(dto);
        return new PageImpl<>((List<ScreenActiveResultDTO>)resultMap.get("resultList"), dto.getPageDto().getPageable(), Long.parseLong(resultMap.get("count")+""));
    }

    public Map<String, Object> getZzFruitData(ScreenSearchConditionDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //省部级以上会议
        List<String> hyLevelList = new ArrayList<>();
        hyLevelList.add("1");
        hyLevelList.add("2");
        hyLevelList.add("3");
        //资政内参和会议
        fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport).or(
                qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice)
                        .and(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEETING)
                                .and(qFruitPO.awardsLevel.in(hyLevelList))
                        )
        ));

        return this.getFruitInfo(dto, fruitPredicate, true, false,false);
    }

    @Override
    public Map<String, List<ScreenActiveResultDTO>> getLlFruitForMaxLeader(ScreenSearchConditionDTO dto) {
        //有明确三报一刊来源的国家级媒体成果
        List<ScreenActiveResultDTO> queryFruitResultsOfMediaHaveSource = getLlFruitForMaxLeader(dto, 1);
        //国家级媒体成果
        List<ScreenActiveResultDTO> queryFruitResultsOfMediaNoSource = getLlFruitForMaxLeader(dto, 2);
        //国家级采访
        List<ScreenActiveResultDTO> queryFruitResultsOfInterview = getLlFruitForMaxLeader(dto, 3);

        Map<String, List<ScreenActiveResultDTO>> map = new HashMap<>();
        map.put("maxLeaderHaveSourceLevelMedia", queryFruitResultsOfMediaHaveSource);
        map.put("maxLeaderNoSourceLevelMedia", queryFruitResultsOfMediaNoSource);
        map.put("maxLeaderLevelInterview", queryFruitResultsOfInterview);
        return map;
    }

    private List<ScreenActiveResultDTO> getLlFruitForMaxLeader(ScreenSearchConditionDTO dto, int type) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QOrgPo qOrgPo = QOrgPo.orgPo;
        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));

        //媒体文章
        Predicate predicate = qFruitPO.type.eq(ComConstant.FruitType.NewspaperORNetwork).and(qFruitPO.publicationLevel.loe("1"));
        if(type == 1){
            //刊载媒体---《人民日报》《光明日报》《经济日报》《求是》 《新华日报》《群众》
            predicate = ExpressionUtils.and(predicate,  qFruitPO.journalName.like("%人民日报%")
                    .or(qFruitPO.journalName.like("%光明日报%"))
                    .or(qFruitPO.journalName.like("%经济日报%"))
                    .or(qFruitPO.journalName.like("%求是%")));
            //党报党刊 纸质媒体 国际媒体
            predicate = ExpressionUtils.and(predicate,  qFruitPO.mediaType.eq("1")
                    .or(qFruitPO.mediaType.eq("3")).or(qFruitPO.mediaType.eq("5")));
        }else if(type == 3){
            predicate = qFruitPO.type.eq(ComConstant.FruitType.NewspaperORNetwork)
                    .and(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEDIA_INTERVIEW))
                    .and(qFruitPO.awardsLevel.loe("2"));
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitPO.pubTime);

        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.loe(sdf.format(pubEndTime)));
        }

        return this.getActiveFruitResults(predicate, qFruitPO, null, qFruitOrgRelPo, qOrgPo, queryAuthor).limit(5).fetch();

    }

    @Override
    public List<ScreenActiveResultDTO> getLlFruit(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getLlFruitData(dto);

        return (List<ScreenActiveResultDTO>)resultMap.get("resultList");
    }

    @Override
    public Page<ScreenActiveResultDTO> getLlFruitOfPage(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getLlFruitData(dto);
        return new PageImpl<>((List<ScreenActiveResultDTO>)resultMap.get("resultList"), dto.getPageDto().getPageable(), Long.parseLong(resultMap.get("count")+""));
    }

    public Map<String, Object> getLlFruitData(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        Predicate mediaLevelPredicate = null;
        //媒体级别
        if(!StringUtils.isEmpty(dto.getLevel())){
            mediaLevelPredicate = qFruitPO.publicationLevel.goe(dto.getLevel());
        }
        //媒体成果和图书出版
        fruitPredicate = ExpressionUtils.and(fruitPredicate,
                (qFruitPO.type.eq(ComConstant.FruitType.NewspaperORNetwork).and(mediaLevelPredicate))
                .or(qFruitPO.type.eq(ComConstant.FruitType.BOOK))
        );

        return this.getFruitInfo(dto, fruitPredicate, true, false,false);
    }

    @Override
    public List<ScreenActiveResultDTO> getZkhdFruit(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getZkhdFruitData(dto);

        return (List<ScreenActiveResultDTO>)resultMap.get("resultList");
    }

    @Override
    public Page<ScreenActiveResultDTO> getZkhdFruitOfPage(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getZkhdFruitData(dto);
        return new PageImpl<>((List<ScreenActiveResultDTO>)resultMap.get("resultList"), dto.getPageDto().getPageable(), Long.parseLong(resultMap.get("count")+""));
    }

    public Map<String, Object> getZkhdFruitData(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //活动
        fruitPredicate = ExpressionUtils.and(fruitPredicate,
                qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).and(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEETING).and(qFruitPO.awardsLevel.goe("3")))
                .or(
                        qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).and(qFruitPO.activityProdType.eq(ComConstant.FruitType.RECEIVE_VISITORS)).and(qFruitPO.awardsLevel.goe("3")))
                .or(
                        qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).and(qFruitPO.activityProdType.eq(ComConstant.FruitType.SURVEY)))
                .or(
                        qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).and(qFruitPO.activityProdType.eq(ComConstant.FruitType.TRAINING))
                )
        );

//        fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitPO.awardsLevel.in(hyLevelList));


        return this.getFruitInfo(dto, fruitPredicate, true, false,false);
    }


    @Override
    public List<ScreenActiveResultDTO> getProjectFruitInfoForMaxLeader(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QOrgPo qOrgPo = QOrgPo.orgPo;
        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));


        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //承担课题  纵向
        fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitPO.type.eq(ComConstant.FruitType.PROJECT)
                .and(qFruitPO.activityProdType.eq(ComConstant.FruitType.VERTICAL))
                .and(qFruitPO.clientLevel.loe("1"))
        );

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitPO.pubTime);

        if (null != pubStartTime) {
            fruitPredicate = ExpressionUtils.and(fruitPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            fruitPredicate = ExpressionUtils.and(fruitPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }

        return this.getActiveFruitResults(fruitPredicate, qFruitPO, null, qFruitOrgRelPo, qOrgPo, queryAuthor).limit(5).fetch();

    }

    @Override
    public List<ScreenActiveResultDTO> getProjectFruit(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getProjectFruitData(dto);

        return (List<ScreenActiveResultDTO>)resultMap.get("resultList");
    }

    @Override
    public Page<ScreenActiveResultDTO> getProjectFruitOfPage(ScreenSearchConditionDTO dto) {
        Map<String, Object> resultMap = this.getProjectFruitData(dto);

        return new PageImpl<>((List<ScreenActiveResultDTO>)resultMap.get("resultList"), dto.getPageDto().getPageable(), Long.parseLong(resultMap.get("count")+""));
    }

    public Map<String, Object> getProjectFruitData(ScreenSearchConditionDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Predicate fruitPredicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);
        //承担课题
        fruitPredicate = ExpressionUtils.and(fruitPredicate, qFruitPO.type.eq(ComConstant.FruitType.PROJECT));

        return this.getFruitInfo(dto, fruitPredicate, true, false,false);
    }

    public Map<String, Object> getFruitInfo(ScreenSearchConditionDTO dto, Predicate predicate, boolean containFruitData, boolean containCnData, boolean containPsData) {
        Map<String, Object> map = new HashMap<>();

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QOrgPo qOrgPo = QOrgPo.orgPo;

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitPO.id));

        Pageable pageable = dto.getPageDto().getPageable();
        List<ScreenActiveResultDTO> queryFruitResults = new ArrayList<>();
        if(containFruitData){
            //成果动态
            JPAQuery<ScreenActiveResultDTO> fruitQuery = this.getActiveFruitResults(predicate, qFruitPO, qFruitLeaderPO, qFruitOrgRelPo, qOrgPo, queryAuthor);
            queryFruitResults.addAll(fruitQuery.fetch());
        }
        if(containCnData){
            //采纳动态--仅单独用于采纳信息展现
            JPAQuery<ScreenActiveResultDTO> cnQuery = this.getActiveCnResults(predicate, qFruitPO, qFruitSubPO, qFruitOrgRelPo, qOrgPo, queryAuthor);
            queryFruitResults.addAll(cnQuery.fetch());
        }
        if(containPsData){
            //批示动态
            JPAQuery<ScreenActiveResultDTO> psQuery = this.getActivePsResults(predicate, qFruitPO, qFruitLeaderPO, qFruitOrgRelPo, qOrgPo, queryAuthor);
            queryFruitResults.addAll(psQuery.fetch());
        }

        //按时间倒序取自定义条数
        List<ScreenActiveResultDTO> resultList = queryFruitResults.stream()
                .filter(screenActiveResultDTO -> screenActiveResultDTO.getFruitTime() != null)
                .sorted(
                        //比较Date
                        Comparator.comparing(ScreenActiveResultDTO::getFruitTime, (d1, d2) -> d1.compareTo(d2)).reversed()
                ).collect(Collectors.toList());

        //合并list
        map.put("count", resultList.size());
        //分页
        int fromIndex = pageable.getPageSize()*pageable.getPageNumber();
        int toIndex = pageable.getPageSize()*(pageable.getPageNumber()+1);
        //#获取当前页数据
        toIndex = Math.min(resultList.size(), toIndex);

        map.put("resultList", resultList.subList(fromIndex, toIndex));

        return map;
    }

    public JPAQuery<ScreenActiveResultDTO> getActiveFruitResults(Predicate predicate, QFruitPO qFruitPO, QFruitLeaderPO qFruitLeaderPO, QFruitOrgRelPo qFruitOrgRelPo, QOrgPo qOrgPo, SubQueryExpression queryAuthor){

        DateTimeExpression timeExpression = new CaseBuilder().when(qFruitPO.type.eq(ComConstant.FruitType.PROJECT)).then(qFruitPO.createTime).otherwise(qFruitPO.pubTime);
        //查询成果动态
        JPAQuery<ScreenActiveResultDTO> queryFruitResults = jpaQueryFactory.select(
                Projections.constructor(ScreenActiveResultDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        timeExpression.as("fruitTime"),
                        queryAuthor,
                        qOrgPo.id,
                        qOrgPo.nameZh,
//                        queryPsMaxLevel,
                        qFruitPO.organizer,
                        qFruitPO.journalName,
                        qFruitPO.press,
                        qFruitPO.theme,
                        qFruitPO.meetingTypeName,
                        qFruitPO.visitTypeName,
                        qFruitPO.awards,
                        qFruitPO.awardsLevelName,
                        qFruitPO.clientLevelName,
                        qFruitPO.summary,
                        qOrgPo.presetMgr.realName,
                        qOrgPo.presetMgr.phoneNumber,
                        qOrgPo.presetMgr.mail
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(predicate)
                .orderBy(
                        qFruitPO.pubTime.desc()
                );
        return queryFruitResults;
    }

    public JPAQuery<ScreenActiveResultDTO> getActiveCnResults(Predicate predicate, QFruitPO qFruitPO, QFruitSubPO qFruitSubPO, QFruitOrgRelPo qFruitOrgRelPo, QOrgPo qOrgPo, SubQueryExpression queryAuthor){

        //查询采纳动态
        JPAQuery<ScreenActiveResultDTO> queryCnResults = jpaQueryFactory.select(
                Projections.constructor(ScreenActiveResultDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitSubPO.subTime.as("fruitTime"),
                        queryAuthor,
                        qOrgPo.nameZh,
                        qFruitSubPO.subDeparment,
                        qFruitSubPO.level,
                        qFruitPO.summary,
                        qOrgPo.presetMgr.realName,
                        qOrgPo.presetMgr.phoneNumber,
                        qOrgPo.presetMgr.mail
                )
        )
                .from(qFruitSubPO)
                .leftJoin(qFruitOrgRelPo).on(qFruitSubPO.fruitId.eq(qFruitOrgRelPo.fruitId))
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(predicate)
                .orderBy(
                        qFruitSubPO.subTime.desc()
                );
        return queryCnResults;
    }


    public JPAQuery<ScreenActiveResultDTO> getActivePsResults(Predicate predicate, QFruitPO qFruitPO, QFruitLeaderPO qFruitLeaderPO, QFruitOrgRelPo qFruitOrgRelPo, QOrgPo qOrgPo, SubQueryExpression queryAuthor){

        //查询批示动态
        JPAQuery<ScreenActiveResultDTO> queryPsResults = jpaQueryFactory.select(
                Projections.constructor(ScreenActiveResultDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitLeaderPO.inclinationTime.as("fruitTime"),
                        queryAuthor,
                        qOrgPo.nameZh,
                        qFruitLeaderPO.name,
                        qFruitLeaderPO.inclinationLevelName,
                        qFruitPO.summary,
                        qOrgPo.presetMgr.realName,
                        qOrgPo.presetMgr.phoneNumber,
                        qOrgPo.presetMgr.mail
                )
        )
                .from(qFruitLeaderPO)
                .leftJoin(qFruitOrgRelPo).on(qFruitLeaderPO.fruitId.eq(qFruitOrgRelPo.fruitId))
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(predicate)
                .orderBy(
                        qFruitLeaderPO.inclinationTime.desc(),
                        qFruitLeaderPO.inclinationLevel.asc()
                );
        return queryPsResults;
    }


    @Override
    public Map getOrgFruitNcInfoOfYear(ScreenSearchConditionDTO dto) {
        Calendar calendar = Calendar.getInstance();
        //2016年到当前年份的数据
        int startYear = 2016;
        int currentYear = calendar.get(Calendar.YEAR);

        Map map = new HashMap();

        //报送次数
        this.getBsCnFruitInfo(map, 1, startYear, currentYear, dto);

        //采纳次数
        this.getBsCnFruitInfo(map, 2, startYear, currentYear, dto);

        //批示次数
        this.getPsFruitInfo(map, startYear, currentYear, dto);

        return map;
    }

    public void getBsCnFruitInfo(Map map, int type, int startYear, int endYear, ScreenSearchConditionDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;


        Predicate predicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);

        // 开启谓语查询条件
        predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.isNotNull().and(qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport)));
        if(type == 2){
            predicate = ExpressionUtils.and(predicate, qFruitSubPO.isAdopt.isTrue());
        }

        List<ScreenYearResultDTO> syrList = new ArrayList<>();
        jpaQueryFactory.select(qFruitSubPO.level, qFruitPO.pubTime.year(), qFruitPO.id.count())
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qFruitSubPO).on(qFruitSubPO.fruitId.eq(qFruitPO.id))
                .where(predicate)
                .groupBy(qFruitSubPO.level, qFruitPO.pubTime.year()).fetch().stream()
                .forEach(
                        tuple -> {
                            ScreenYearResultDTO yearResultDTO = new ScreenYearResultDTO();
                            yearResultDTO.setLevel(tuple.get(qFruitSubPO.level));
                            yearResultDTO.setYear(tuple.get(qFruitPO.pubTime.year()));
                            yearResultDTO.setCount(tuple.get(qFruitPO.id.count()).intValue());
                            syrList.add(yearResultDTO);
                        }
                );
        //国家级
        List<Integer> yearGjjDataList = new ArrayList<>();
        //省部级
        List<Integer> yearSbjDataList = new ArrayList<>();
        //拼接2016-至今的年份数据
        for (int i = startYear; i <= endYear; i++) {
            int yearGjjCount = 0;
            int yearSbjCount = 0;
            for (ScreenYearResultDTO syr : syrList) {
                if(i == syr.getYear()){
                    if(("1").equals(syr.getLevel()) || ("2").equals(syr.getLevel())) {
                        yearGjjCount += syr.getCount();
                    }else if(("3").equals(syr.getLevel()) || ("4").equals(syr.getLevel())){
                        yearSbjCount += syr.getCount();
                    }
                }
            }
            yearGjjDataList.add(yearGjjCount);
            yearSbjDataList.add(yearSbjCount);
        }
        if(type == 1){
            map.put("bsGjjYearList", yearGjjDataList);
            map.put("bsSbjYearList", yearSbjDataList);
        }else if(type == 2){
            map.put("cnGjjYearList", yearGjjDataList);
            map.put("cnSbjYearList", yearSbjDataList);
        }
    }

    public void getPsFruitInfo(Map map, int startYear, int endYear, ScreenSearchConditionDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        // 开启谓语查询条件
        Predicate predicate = this.getFruitAndOrgRelPredicate(qFruitPO, qFruitOrgRelPo, dto);

        predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.isNotNull().and(qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport)));

        List<ScreenYearResultDTO> syrList = new ArrayList<>();

        jpaQueryFactory.select(qFruitLeaderPO.inclinationLevel, qFruitPO.pubTime.year(), qFruitPO.id.count())
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qFruitLeaderPO).on(qFruitLeaderPO.fruitId.eq(qFruitPO.id))
                .where(predicate)
                .groupBy(qFruitLeaderPO.inclinationLevel, qFruitPO.pubTime.year()).fetch().stream()
                .forEach(
                        tuple -> {
                            ScreenYearResultDTO yearResultDTO = new ScreenYearResultDTO();
                            yearResultDTO.setLevel(tuple.get(qFruitLeaderPO.inclinationLevel));
                            yearResultDTO.setYear(tuple.get(qFruitPO.pubTime.year()));
                            yearResultDTO.setCount(tuple.get(qFruitPO.id.count()).intValue());
                            syrList.add(yearResultDTO);
                        }
                );;
        //国家级
        List<Integer> yearGjjDataList = new ArrayList<>();
        //省部级
        List<Integer> yearSbjDataList = new ArrayList<>();
        //拼接2016-至今的年份数据
        for (int i = startYear; i <= endYear; i++) {
            int yearGjjCount = 0;
            int yearSbjCount = 0;
            for (ScreenYearResultDTO syr : syrList) {
                if(i == syr.getYear()){
                    if(("1").equals(syr.getLevel()) || ("2").equals(syr.getLevel())) {
                        yearGjjCount += syr.getCount();
                    }else if(("3").equals(syr.getLevel()) || ("4").equals(syr.getLevel())){
                        yearSbjCount += syr.getCount();
                    }
                }
            }
            yearGjjDataList.add(yearGjjCount);
            yearSbjDataList.add(yearSbjCount);
        }
        map.put("psGjjYearList", yearGjjDataList);
        map.put("psSbjYearList", yearSbjDataList);

    }

    @Override
    public Map getOrgLlFruitInfoCountOfYear(ScreenSearchConditionDTO dto) {

        Calendar calendar = Calendar.getInstance();
        //2016年到当前年份的数据
        int startYear = 2016;
        int currentYear = calendar.get(Calendar.YEAR);

        Long userId = ServiceAccountHelper.getUserId();
        //获取当前人权限下的所有机构
        Set<Long> allOrgIdList = OrgAccountHelper.getOrgIdList();
        //获取当前人权限下的所有机构分类
        Map<String, Set<Long>> orgIdMap = orgRoleService.findOrgsByClassify(userId);
        //省重点智库
        Set<Long> pointOrgIds = orgIdMap.get("point");
        //省培育
        Set<Long> fosterOrgIds = orgIdMap.get("foster");

        Map map = new HashMap();
        //国际
        List<Integer> yearGjDataList = new ArrayList<>();
        //国家级
        List<Integer> yearGjjDataList = new ArrayList<>();
        //省部级
        List<Integer> yearSbjDataList = new ArrayList<>();
        //厅局级
        List<Integer> yearTjjDataList = new ArrayList<>();
        //媒体成果--级别区分
        this.getFruitLevelCount(map, yearGjDataList, yearGjjDataList, yearSbjDataList, yearTjjDataList, allOrgIdList, startYear, currentYear, ComConstant.FruitType.NewspaperORNetwork, "");
        map.put("mediaGjYearList", yearGjDataList);
        map.put("mediaGjjYearList", yearGjjDataList);
        map.put("mediaSbjYearList", yearSbjDataList);
        map.put("mediaTjjYearList", yearTjjDataList);
        //论文
        map.put("pointLw", this.getOrgClassifyFruitCount(ComConstant.FruitType.Paper, "", pointOrgIds, startYear, currentYear));
        map.put("fosterLw", this.getOrgClassifyFruitCount(ComConstant.FruitType.Paper, "", fosterOrgIds, startYear, currentYear));
        //图书
        map.put("pointTs", this.getOrgClassifyFruitCount(ComConstant.FruitType.BOOK, "", pointOrgIds, startYear, currentYear));
        map.put("fosterTs", this.getOrgClassifyFruitCount(ComConstant.FruitType.BOOK, "", fosterOrgIds, startYear, currentYear));

        return map;
    }


    private void getFruitLevelCount(Map map, List<Integer> yearGjDataList, List<Integer> yearGjjDataList, List<Integer> yearSbjDataList, List<Integer> yearTjjDataList,
                                    Set<Long> orgIdList, int startYear, int endYear, String type, String activityProType) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse())
                .and(qFruitPO.isPublic.eq("0").and(qFruitPO.type.eq(type))
                        .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)));
        if(!StringUtils.isEmpty(activityProType)){
            predicate = ExpressionUtils.and(predicate, qFruitPO.activityProdType.eq(activityProType));
        }
        //查询的级别字段
        StringPath queryColumn = ComConstant.FruitType.NewspaperORNetwork.equals(type) ? qFruitPO.publicationLevel: qFruitPO.awardsLevel;

        List<ScreenYearResultDTO> syrList = new ArrayList<>();

        jpaQueryFactory.select(
                queryColumn,
                qFruitPO.pubTime.year(),
                qFruitPO.id.count()
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId))
                .where(predicate)
                .where(qFruitPO.pubTime.year().between(startYear, endYear).and(qFruitOrgRelPo.orgId.in(orgIdList)))
                .groupBy(queryColumn,qFruitPO.pubTime.year())
                .fetch().stream()
                .forEach(
                        tuple -> {
                            ScreenYearResultDTO yearResultDTO = new ScreenYearResultDTO();
                            yearResultDTO.setLevel(tuple.get(queryColumn));
                            yearResultDTO.setYear(tuple.get(qFruitPO.pubTime.year()));
                            yearResultDTO.setCount(tuple.get(qFruitPO.id.count()).intValue());
                            syrList.add(yearResultDTO);
                        }
                );
        //拼接2016-至今的年份数据
        for (int i = startYear; i <= endYear; i++) {
            int yearGjCount = 0;
            int yearGjjCount = 0;
            int yearSbjCount = 0;
            int yearTjjCount = 0;
            for (ScreenYearResultDTO syr : syrList) {
                if(i == syr.getYear()){
                    if(("1").equals(syr.getLevel())){
                        yearGjCount = syr.getCount();
                    }else if(("2").equals(syr.getLevel())){
                        yearGjjCount = syr.getCount();
                    }else if(("3").equals(syr.getLevel())){
                        yearSbjCount = syr.getCount();
                    }else if(("4").equals(syr.getLevel())){
                        yearTjjCount = syr.getCount();
                    }
                }
            }
            yearGjDataList.add(yearGjCount);
            yearGjjDataList.add(yearGjjCount);
            yearSbjDataList.add(yearSbjCount);
            yearTjjDataList.add(yearTjjCount);
        }
    }

    private long getFruitLevelAndDatePeriodCount(ScreenSearchConditionDTO dto, String level, String type, String activityProType) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse())
                .and(qFruitPO.isPublic.eq("0").and(qFruitPO.type.eq(type))
                    .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)))
                .and(qFruitOrgRelPo.orgId.in(dto.getOrgIdList()));
        if(!StringUtils.isEmpty(activityProType)){
            predicate = ExpressionUtils.and(predicate, qFruitPO.activityProdType.eq(activityProType));
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitPO.pubTime);

        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, dateExpr.loe(sdf.format(pubEndTime)));
        }
        if(!StringUtils.isEmpty(level)){
            //查询的级别字段  国家级以上
            if (ComConstant.FruitType.NewspaperORNetwork.equals(type)) {
                predicate = ExpressionUtils.and(predicate, qFruitPO.publicationLevel.eq(level));
            }else if (ComConstant.FruitType.PolicyAdvice.equals(type)) {
                if(ComConstant.FruitType.RECEIVE_VISITORS.equals(activityProType)){
                    predicate = ExpressionUtils.and(predicate, qFruitPO.awardsLevel.eq(level));
                }
            }else if (ComConstant.FruitType.PROJECT.equals(type)) {
                if(ComConstant.FruitType.VERTICAL.equals(activityProType)){
                    predicate = ExpressionUtils.and(predicate, qFruitPO.clientLevel.eq(level));
                }
            }
        }
        return jpaQueryFactory.select(qFruitPO.id.count())
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId))
                .where(predicate)
                .fetchCount();
    }

    /**
     * @param orgIdList
     * @param startYear
     * @param endYear
     * @return
     */
    public List<ResultDTO> getOrgClassifyFruitCount(String type, String activityProType, Set<Long> orgIdList, int startYear, int endYear){
        QFruitPO qFruitPO = QFruitPO.fruitPO;

        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse().and(qFruitPO.type.eq(type)));

        if(!StringUtils.isEmpty(activityProType)){
            predicate = ExpressionUtils.and(predicate, qFruitPO.activityProdType.eq(activityProType));
        }

        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        List<ResultDTO> results = new ArrayList<>();

        Map<Integer, Integer> map = new HashMap<>();
        jpaQueryFactory.select(qFruitPO.pubTime.year(), qFruitPO.id.count())
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .where(qFruitPO.isPublic.eq("0")
                        .and(qFruitOrgRelPo.orgId.in(orgIdList)
                                .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED))))
                .where(predicate).where(qFruitPO.pubTime.year().between(startYear, endYear))
                .groupBy(qFruitPO.pubTime.year()).fetch()
                .forEach(
                        tuple -> {
                            map.put(tuple.get(qFruitPO.pubTime.year().intValue()), tuple.get(qFruitPO.id.count()).intValue());
                        }
                );
        for (int i = startYear; i <= endYear; i++) {
            ResultDTO resultDTO = new ResultDTO();
            resultDTO.setName(i + "");
            resultDTO.setValue(map.get(i) == null ? 0 : map.get(i));
            results.add(resultDTO);
        }
        return results;

    }

    @Override
    public Map getZkhdFruitInfoCountOfYear(ScreenSearchConditionDTO dto) {

        Calendar calendar = Calendar.getInstance();
        //2016年到当前年份的数据
        int startYear = 2016;
        int currentYear = calendar.get(Calendar.YEAR);
        //获取当前人权限下的所有机构
        Set<Long> allOrgIdList = dto.getOrgIdList();

        Map map = new HashMap();
        //国际
        List<Integer> yearGjDataList = new ArrayList<>();
        //国家级
        List<Integer> yearGjjDataList = new ArrayList<>();
        //省部级
        List<Integer> yearSbjDataList = new ArrayList<>();
        //厅局级
        List<Integer> yearTjjDataList = new ArrayList<>();
        //接受采访成果--级别区分
        this.getFruitLevelCount(map, yearGjDataList, yearGjjDataList, yearSbjDataList, yearTjjDataList, allOrgIdList, startYear, currentYear, ComConstant.FruitType.NewspaperORNetwork, ComConstant.FruitType.MEDIA_INTERVIEW);
        map.put("cfGjYearList", yearGjDataList);
        map.put("cfGjjYearList", yearGjjDataList);
        map.put("cfSbjYearList", yearSbjDataList);
        map.put("cfTjjYearList", yearTjjDataList);

        //主旨论坛
        List<ScreenYearResultDTO> bbsList = new ArrayList<>();

        map.put("bbsList", bbsList);

        return map;
    }


    @Override
    public Map getAllOrgProjectCountOfYear(ScreenSearchConditionDTO dto) {
        Calendar calendar = Calendar.getInstance();
        //2016年到当前年份的数据
        int startYear = 2016;
        int currentYear = calendar.get(Calendar.YEAR);

        //权限下的智库
        Long userId = ServiceAccountHelper.getUserId();
        //获取当前人权限下的所有机构
        Map<String, Set<Long>> orgIdMap = orgRoleService.findOrgsByClassify(userId);
        //省重点智库
        Set<Long> pointOrgIds = orgIdMap.get("point");
        //省培育
        Set<Long> fosterOrgIds = orgIdMap.get("foster");

        Map map = new HashMap();
        map.put("point", this.getOrgClassifyFruitProjectCount(ComConstant.FruitType.PROJECT, pointOrgIds, startYear, currentYear));
        map.put("foster", this.getOrgClassifyFruitProjectCount(ComConstant.FruitType.PROJECT,  fosterOrgIds, startYear, currentYear));

        return map;
    }

    /**
     * 获取智库2016年至今的课题分类数据
     * @param orgIdList
     * @param startYear
     * @param endYear
     * @return
     */
    public List<ResultDTO> getOrgClassifyFruitProjectCount(String type, Set<Long> orgIdList, int startYear, int endYear){
        QFruitPO qFruitPO = QFruitPO.fruitPO;

        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse().and(qFruitPO.type.eq(type)));

        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        List<ResultDTO> results = new ArrayList<>();

        Map<Integer, Integer> map = new HashMap<>();
        jpaQueryFactory.select(qFruitPO.completionTime.year(), qFruitPO.id.count())
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .where(qFruitPO.isPublic.eq("0")
                        .and(qFruitOrgRelPo.orgId.in(orgIdList)
                                .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED))))
                .where(predicate).where(qFruitPO.completionTime.year().between(startYear, endYear))
                .groupBy(qFruitPO.completionTime.year()).fetch()
                .forEach(
                        tuple -> {
                            map.put(tuple.get(qFruitPO.completionTime.year().intValue()), tuple.get(qFruitPO.id.count()).intValue());
                        }
                );

        for (int i = startYear; i <= endYear; i++) {
            ResultDTO resultDTO = new ResultDTO();
            resultDTO.setName(i + "");
            resultDTO.setValue(map.get(i) == null ? 0 : map.get(i));
            results.add(resultDTO);
        }

        return results;

    }


}
